


valor(mina).
valor(X):- between(0,8,X).


%dim(+T,-Cols,-Fils)
dim(T,Cols,Fils):- length(T,Fils), nth1(1,T,T2),length(T2,Cols).

%pos(+T,-C,-F)
pos(T,C,F):- dim(T,Cols,Fils),between(1,Cols,C),between(1,Fils,F).


%nonvars(?L,-R)
nonvars([], []).
nonvars([X|XS],YS):- var(X), nonvars(XS,YS).
nonvars([X|XS],[X|YS]):- nonvar(X), nonvars(XS,YS).

%cant minas(?L, -N)
cant_minas([],0).
cant_minas([X|XS], N) :- nonvar(X), X == mina, cant_minas(XS,M), N is M+1.
cant_minas([X|XS], N) :- var(X), cant_minas(XS,N).
cant_minas([X|XS],N):- X \= mina, cant_minas(XS,N).

damepos(T,C,F,X):- nth1(F,T,Fila),nth1(C,Fila,X).


%vecinos(+T, +C, +F, -L)
vecinos(T,C,F,L):-  bagof(X,vecino(T,C,F,X) , L).

vecino(T,C,F,X):- nth1(F2,T,Fila),nth1(C2,Fila,Elem), X=Elem, F2 is F-1, C2 is C-1.
vecino(T,C,F,X):- nth1(F2,T,Fila),nth1(C2,Fila,Elem), X=Elem, F2 is F-1, C2 is C.
vecino(T,C,F,X):- nth1(F2,T,Fila),nth1(C2,Fila,Elem), X=Elem, F2 is F-1, C2 is C+1.
vecino(T,C,F,X):- nth1(F2,T,Fila),nth1(C2,Fila,Elem), X=Elem, F2 is F, C2 is C-1.
vecino(T,C,F,X):- nth1(F2,T,Fila),nth1(C2,Fila,Elem), X=Elem, F2 is F, C2 is C+1.
vecino(T,C,F,X):- nth1(F2,T,Fila),nth1(C2,Fila,Elem), X=Elem, F2 is F+1, C2 is C-1.
vecino(T,C,F,X):- nth1(F2,T,Fila),nth1(C2,Fila,Elem), X=Elem, F2 is F+1, C2 is C.
vecino(T,C,F,X):- nth1(F2,T,Fila),nth1(C2,Fila,Elem), X=Elem, F2 is F+1, C2 is C+1.

%consistente (+T, +C, +F)

consistente(T, C, F):- damepos(T,C,F,X), X = mina.
consistente(T, C, F):- damepos(T,C,F,X), not(X = mina), vecinos(T,C,F,L),cant_minas(L,N), X is N.

%consistente(+T)
consistente(T):- findall(C*F,consistente(T,C,F),L),dim(T,Cols,Fils), length(L,Largo), Largo is (Cols * Fils).


%completarA([[]]).
%completarA([]|Filas):- completarA(Filas).
% completarA([[Elem|RestoFila]|Filas]):- var(Elem),
% valor(Elem),completarA([RestoFila|Filas]).
% completarA([[Elem|RestoFila]|Filas]):- nonvar(Elem),
% completarA([RestoFila|Filas]).

%completarA(?T)
valorizar([]).
valorizar([X|XS]):- var(X), valor(X), valorizar(XS).
valorizar([X|XS]):- nonvar(X), valorizar(XS).

completarA(T):- generarA(T), consistente(T).

generarA([]).
generarA([Fila|T]) :- generarA_lista(Fila), generarA(T).

generarA_lista([]).
generarA_lista([H|T]) :- generarA_celda(H), generarA_lista(T).

generarA_celda(C) :- nonvar(C).
generarA_celda(C) :- var(C), valor(C).

%completarB(?T)
completarB(T):-generarB(T, T, 1), consistente(T).

generarB([], _, _).
generarB([Fila|Fs], T, F) :- generarB_lista(Fila, T, 1, F), F2 is F+1, generarB(Fs, T, F2).

generarB_lista([], _, _, _).
generarB_lista([Columna|Cs], T, C, F) :- generarB_celda(Columna), C2 is C+1, generarB_lista(Cs, T, C2, F), validarB(T, C2, F).

generarB_celda(X) :- nonvar(X).
generarB_celda(X) :- var(X), valor(X).

validarB(_, 1, F) :- F \= 1.
validarB(_, C, 1) :- C \= 1.
validarB(T, C, F) :- C \= 1, F \= 1, dim(T, C, _), Fm1 is F-1, consistente(T, C, Fm1).
validarB(T, C, F) :- C \= 1, F \= 1, dim(T, C2, F), C \= C2, Cm1 is C-1, consistente(T, Cm1, F).
validarB(T, C, F) :- C \= 1, F \= 1, dim(T, C2, F2), C \= C2, F \= F2, Cm1 is C-1, Fm1 is F-1, consistente(T, Cm1, Fm1).

%completarC(?T)
completarC(T):-generarC(T, T, 1), consistente(T).

generarC([], _, _).
generarC([Fila|Fs], T, NFila) :- generarC_fila(Fila, T, 1, NFila), F2 is NFila+1, generarC(Fs, T, F2).
 
generarC_fila([], _, _, _).
generarC_fila([Columna|Cs], T, NCol, NFila) :- generarC_celda(Columna, T, NCol, NFila), NCol2 is NCol+1, generarC_fila(Cs, T, NCol2, NFila).

generarC_celda(X, _, _, _) :- nonvar(X).
generarC_celda(X, T, NCol, NFila) :- var(X), valor(X), validarC(X, T,NCol, NFila).

validarC(mina, T, NCol, NFila) :- vecinos(T, NCol, NFila, Vecinos),
                                    nonvars(Vecinos, VecinosInstanciados),
                                    non_member(0, VecinosInstanciados).
validarC(X, T, NCol, NFila) :- X \= mina,
                                vecinos(T,NCol, NFila, Vecinos),
                                nonvars(Vecinos, VecinosInstanciados),
                                cant_minas(VecinosInstanciados, CantMinasVecinas),
                                length(Vecinos, CantVecinos),
                                length(VecinosInstanciados, CantVecinosInstanciados),
                                CantVecinosNoInstanciados is CantVecinos-CantVecinosInstanciados,
                                CantMaxMinas is CantMinasVecinas+CantVecinosNoInstanciados,
                                between(CantMinasVecinas, CantMaxMinas, X).

non_member(X,Y) :- member(X,Y), !, fail.
non_member(_,_).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
pre_r(N,T) :- get_time(T1), stamp_date_time(T1, X1, 'UTC'), write(X1), nl, problem(N,T).
post_r(T) :- mostrar(T), get_time(T2), stamp_date_time(T2, X2, 'UTC'), write(X2).

rA(N,T) :- pre_r(N,T), completarA(T), post_r(T).
rB(N,T) :- pre_r(N,T), completarB(T), post_r(T).
rC(N,T) :- pre_r(N,T), completarC(T), post_r(T).

mostrar([]).
mostrar([Fila|T]) :-
	mostrar_lista(Fila),
	mostrar(T).

mostrar_lista([]) :- nl.
mostrar_lista([H|T]) :- mostrar_celda(H), mostrar_lista(T).

mostrar_celda(C) :- nonvar(C), C == mina, write('*').
mostrar_celda(C) :-	nonvar(C), C \= mina, write(C).
mostrar_celda(C) :- var(C), write('_').


problem(t1, [[_,_],
			 [_,1]]).

problem(t2, [[_,_],
			 [_,2]]).

problem(t3, [[_,_],
			 [_,3]]).

problem(t4, [[0,_,_],
			 [_,1,_],
			 [_,_,0]]).

problem(t5, [[0,_,_],
			 [_,1,_]
			 ]).

problem(t6, [[_,_,_],
			 [_,1,_],
			 [0,1,1]]).


%Problem from Gecode/examples/minesweeper.cc  problem 0
%
% Solution:
%  1 0 0 0 0 1
%  0 1 0 1 1 0
%  0 0 0 0 1 0
%  0 0 0 0 1 0
%  0 1 1 1 0 0
%  1 0 0 0 1 1
%
problem(0,[[_,_,2,_,3,_],
           [2,_,_,_,_,_],
           [_,_,2,4,_,3],
           [1,_,3,4,_,_],
           [_,_,_,_,_,3],
           [_,3,_,3,_,_]]).



% Problem from Gecode/examples/minesweeper.cc  problem 1
problem(1,[[_,2,_,2,1,1,_,_],
           [_,_,4,_,2,_,_,2],
           [2,_,_,2,_,_,3,_],
           [2,_,2,2,_,3,_,3],
           [_,_,1,_,_,_,4,_],
           [1,_,_,_,2,_,_,3],
           [_,2,_,2,2,_,3,_],
           [1,_,1,_,_,1,_,1]]).



% Problem from Gecode/examples/minesweeper.cc  problem 2
problem(2,[[1,_,_,2,_,2,_,2,_,_],
           [_,3,2,_,_,_,4,_,_,1],
           [_,_,_,1,3,_,_,_,4,_],
           [3,_,1,_,_,_,3,_,_,_],
           [_,2,1,_,1,_,_,3,_,2],
           [_,3,_,2,_,_,2,_,1,_],
           [2,_,_,3,2,_,_,2,_,_],
           [_,3,_,_,_,3,2,_,_,3],
           [_,_,3,_,3,3,_,_,_,_],
           [_,2,_,2,_,_,_,2,2,_]]).


% Problem from Gecode/examples/minesweeper.cc  problem 3
problem(3,[[2,_,_,_,3,_,1,_],
           [_,5,_,4,_,_,_,1],
           [_,_,5,_,_,4,_,_],
           [2,_,_,_,4,_,5,_],
           [_,2,_,4,_,_,_,2],
           [_,_,5,_,_,4,_,_],
           [2,_,_,_,5,_,4,_],
           [_,3,_,3,_,_,_,2]]).


% Problem from Gecode/examples/minesweeper.cc  problem 4
problem(4,[[0,_,0,_,1,_,_,1,1,_],
           [1,_,2,_,2,_,2,2,_,_],
           [_,_,_,_,_,_,2,_,_,2],
           [_,2,3,_,1,1,_,_,_,_],
           [0,_,_,_,_,_,_,2,_,1],
           [_,_,_,2,2,_,1,_,_,_],
           [_,_,_,_,_,3,_,3,2,_],
           [_,5,_,2,_,_,_,3,_,1],
           [_,3,_,1,_,_,3,_,_,_],
           [_,2,_,_,_,1,2,_,_,0]]).


% Problem from Gecode/examples/minesweeper.cc  problem 5
problem(5,[[_,2,1,_,2,_,2,_,_,_],
           [_,4,_,_,3,_,_,_,5,3],
           [_,_,_,4,_,4,4,_,_,3],
           [4,_,4,_,_,5,_,6,_,_],
           [_,_,4,5,_,_,_,_,5,4],
           [3,4,_,_,_,_,5,5,_,_],
           [_,_,4,_,4,_,_,5,_,5],
           [2,_,_,3,3,_,6,_,_,_],
           [3,6,_,_,_,3,_,_,4,_],
           [_,_,_,4,_,2,_,2,1,_]]).



% Problem from Gecode/examples/minesweeper.cc  problem 6
problem(6,[[_,3,2,_,_,1,_,_],
           [_,_,_,_,1,_,_,3],
           [3,_,_,2,_,_,_,4],
           [_,5,_,_,_,5,_,_],
           [_,_,6,_,_,_,5,_],
           [3,_,_,_,5,_,_,4],
           [2,_,_,5,_,_,_,_],
           [_,_,2,_,_,3,4,_]]).


% Problem from Gecode/examples/minesweeper.cc  problem 7
problem(7,[[_,1,_,_,_,_,_,3,_],
           [_,_,_,3,4,3,_,_,_],
           [2,4,4,_,_,_,4,4,3],
           [_,_,_,4,_,4,_,_,_],
           [_,4,_,4,_,3,_,6,_],
           [_,_,_,4,_,3,_,_,_],
           [1,2,3,_,_,_,1,3,3],
           [_,_,_,3,2,2,_,_,_],
           [_,2,_,_,_,_,_,3,_]]).



% Problem from Gecode/examples/minesweeper.cc  problem 8
problem(8,[[_,_,_,_,_,_,_],
           [_,2,3,4,3,5,_],
           [_,1,_,_,_,3,_],
           [_,_,_,5,_,_,_],
           [_,1,_,_,_,3,_],
           [_,1,2,2,3,4,_],
           [_,_,_,_,_,_,_]]).


% Problem from Gecode/examples/minesweeper.cc  problem 9
problem(9,[[2,_,_,_,2,_,_,_,2],
           [_,4,_,4,_,3,_,4,_],
           [_,_,4,_,_,_,1,_,_],
           [_,4,_,3,_,3,_,4,_],
           [2,_,_,_,_,_,_,_,2],
           [_,5,_,4,_,5,_,4,_],
           [_,_,3,_,_,_,3,_,_],
           [_,4,_,3,_,5,_,6,_],
           [2,_,_,_,1,_,_,_,2]]).



% From "Some Minesweeper Configurations",page 2
problem(10,[[_,_,_,_,_,_],
            [_,2,2,2,2,_],
            [_,2,0,0,2,_],
            [_,2,0,0,2,_],
            [_,2,2,2,2,_],
            [_,_,_,_,_,_]]).



% From "Some Minesweeper Configurations",page 3
% 4 solutions
problem(11,[[2,3,_,2,2,_,2,1],
            [_,_,4,_,_,4,_,2],
            [_,_,_,_,_,_,4,_],
            [_,5,_,6,_,_,_,2],
            [2,_,_,_,5,5,_,2],
            [1,3,4,_,_,_,4,_],
            [0,1,_,4,_,_,_,3],
            [0,1,2,_,2,3,_,2]]).


% Richard Kaye: How Complicated is Minesweeper?
% http://web.mat.bham.ac.uk/R.W.Kaye/minesw/ASE2003.pdf
%
% A Wire,page 33
% 2 solutions
%
problem(12,[[_,0,0,0,0,0,0,0,0,0,0,0,0,_],
            [_,1,1,1,1,1,1,1,1,1,1,1,1,_],
            [_,_,1,_,_,1,_,_,1,_,_,1,_,_],
            [_,1,1,1,1,1,1,1,1,1,1,1,1,_],
            [_,0,0,0,0,0,0,0,0,0,0,0,0,_]]).


% Richard Kaye: How Complicated is Minesweeper?
% http://web.mat.bham.ac.uk/R.W.Kaye/minesw/ASE2003.pdf
% A splitter,page 35
% Many solutions...
%
problem(13,[[_,_,_,0,_,_,_,0,_,_,_],
            [_,_,_,0,1,_,1,0,_,_,_],
            [_,_,_,0,1,_,1,0,_,_,_],
            [0,0,0,0,1,1,1,0,0,0,0],
            [_,1,1,1,1,_,1,1,1,1,_],
            [_,_,_,1,_,2,_,1,_,_,_],
            [_,1,1,1,1,_,1,1,1,1,_],
            [0,0,0,0,1,1,1,0,0,0,0],
            [_,_,_,0,1,_,1,0,_,_,_],
            [_,_,_,0,1,_,1,0,_,_,_],
            [_,_,_,0,_,_,_,0,_,_,_]]).



% Oleg German,Evgeny Lakshtanov: "Minesweeper" without a computer
% http://arxiv.org/abs/0806.3480,page 4
problem(14,[[_,1,_,1,_,1],
            [2,_,2,_,1,_],
            [_,3,_,2,_,1],
            [1,_,3,_,2,_],
            [_,1,_,2,_,1]]).















